package sys_ctl

import (
	"crypto/md5"
	"fmt"
	"net/http"
	"ubt-rbac-service/internal/app/model"
	"ubt-rbac-service/internal/app/model/sys_mod"
	"ubt-rbac-service/internal/app/service/sys_serv"
	"ubt-rbac-service/internal/app/util"
	"ubt-rbac-service/internal/core/convert"
	"ubt-rbac-service/internal/core/parse"
)

type sysUser struct{}

var SysUserCtl sysUser

// Login 用户登录
func (c *sysUser) Login(w http.ResponseWriter, r *http.Request) {
	// 将请求的参数转换为请求结构体
	vo, errStr := parse.Parse(r, &sys_mod.SysUserLoginReq{})
	if vo == nil {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: errStr})
		return
	}
	req := vo.(*sys_mod.SysUserLoginReq)
	// 过滤关键参数值中的非法字符
	req.Usname = util.InputFilter(req.Usname, true)
	req.Passwd = util.InputFilter(req.Passwd, true)
	req.Chcode = util.InputFilter(req.Chcode, true)
	// 获取图形验证码的字符并校验
	sysCode := util.GetSysCode()
	if sysCode == "" || req.Chcode != sysCode {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: "对不起，您输入的验证码不正确，请重试！"})
		return
	}
	// 密码加密
	req.Passwd = fmt.Sprintf("%x", md5.Sum([]byte(req.Passwd)))
	// 登录并返回token
	result, userId, optOrg := sys_serv.SysUserServ.Login(req)
	if result != nil && result.RetCode == 1001 {
		logReq := &sys_mod.SysLogSaveReq{UserId: userId, ModCode: "10010105", Kind: 6, OptOrg: optOrg}
		sys_serv.SysLogServ.Add(logReq)
		util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok", Data: result.RetData})
	} else {
		util.ToJson(w, &model.ResJson{Code: 500, Msg: result.RetMsg})
	}
}

// Session 获取用户缓冲信息
func (c *sysUser) Session(w http.ResponseWriter, r *http.Request) {
	token := r.Header.Get("token")
	// 通过头部请求的token获取用户信息
	if userInfo := util.GetUserInfo(token); userInfo != nil {
		userInfo.ClientIp = util.GetClientIP(r)
		fmt.Printf("客户端IP：%v" + userInfo.ClientIp)
		util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok", Data: userInfo})
	} else {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，您未登录或登录超时，请登录！"})
	}
}

// Exit 用户登出
func (c *sysUser) Exit(w http.ResponseWriter, r *http.Request) {
	token := r.Header.Get("token")
	// 判断缓冲中的用户信息是否为空，不为空则清空
	if userInfo := util.GetUserInfo(token); userInfo != nil {
		req := &sys_mod.SysUserExitReq{UserId: userInfo.UserId, Token: token}
		sys_serv.SysUserServ.Exit(req)
	}
	util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok"})
}

// Save 保存用户
func (c *sysUser) Save(w http.ResponseWriter, r *http.Request) {
	// 将请求的参数转换为请求结构体
	vo, errStr := parse.Parse(r, &sys_mod.SysUserSaveReq{})
	if vo == nil {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: errStr})
		return
	}
	req := vo.(*sys_mod.SysUserSaveReq)
	// 通过头部请求的token获取用户信息
	token := r.Header.Get("token")
	userInfo := util.GetUserInfo(token)
	if userInfo == nil {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，您未登录或登录超时，请登录！"})
		return
	}
	// 过滤关键参数值中的非法字符
	req.UserId = util.InputFilter(req.UserId, true)
	req.Usname = util.InputFilter(req.Usname, true)
	req.NickName = util.InputFilter(req.NickName, true)
	req.Mobile = util.InputFilter(req.Mobile, true)
	req.RoleId = util.InputFilter(req.RoleId, true)
	req.DeptId = util.InputFilter(req.DeptId, true)
	// 判断用户密码
	passwd := req.Passwd
	userId := req.UserId
	if (userId == "" && (passwd == "" || len(passwd) < 6 || len(passwd) > 30)) || (userId != "" && passwd != "" && (len(passwd) < 6 || len(passwd) > 30)) {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，登录密码为空，或长度不是6至30位，请检查！"})
		return
	}
	// 判断编码是否重复
	extVo := &sys_mod.SysUserExtVo{UserId: req.UserId, Usname: req.Usname, Mobile: req.Mobile}
	if ext := sys_serv.SysUserServ.Exists(extVo); ext {
		util.ToJson(w, &model.ResJson{Code: 402, Msg: "对不起，填写的账号或手机号已存在，请更换！"})
		return
	}
	// 判断是否修改密码
	if req.Passwd != "" {
		req.Passwd = fmt.Sprintf("%x", md5.Sum([]byte(req.Passwd)))
	}
	var (
		result *model.Result
		kind   uint8
	)
	if req.UserId == "" {
		// 新增
		result = sys_serv.SysUserServ.Add(req)
		kind = 1
	} else {
		// 修改
		result = sys_serv.SysUserServ.Update(req)
		kind = 3
	}
	if result != nil && result.RetCode == 1001 {
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, ModCode: "10010105", Kind: kind, OptOrg: userInfo.DeptId}
		sys_serv.SysLogServ.Add(logReq)
		util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok"})
	} else {
		util.ToJson(w, &model.ResJson{Code: 500, Msg: result.RetMsg})
	}
}

// Process 审核删除用户
func (c *sysUser) Process(w http.ResponseWriter, r *http.Request) {
	// 将请求的参数转换为请求结构体
	vo, errStr := parse.Parse(r, &sys_mod.SysUserProReq{})
	if vo == nil {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: errStr})
		return
	}
	req := vo.(*sys_mod.SysUserProReq)
	// 通过头部请求的token获取用户信息
	token := r.Header.Get("token")
	userInfo := util.GetUserInfo(token)
	if userInfo == nil {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，您未登录或登录超时，请登录！"})
		return
	}
	// 过滤关键参数值中的非法字符
	req.UserIds = util.InputFilter(req.UserIds, true)
	result := sys_serv.SysUserServ.Process(req)
	if result != nil && result.RetCode == 1001 {
		var kind uint8
		switch req.States {
		case 1:
			kind = 4
		case 3:
			kind = 5
		case 2:
			kind = 2
		default:
			kind = 2
		}
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, ModCode: "10010105", Kind: kind, OptOrg: userInfo.DeptId}
		sys_serv.SysLogServ.Add(logReq)
		util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok"})
	} else {
		util.ToJson(w, &model.ResJson{Code: 500, Msg: result.RetMsg})
	}
}

// Personal 修改个人资料
func (c *sysUser) Personal(w http.ResponseWriter, r *http.Request) {
	// 将请求的参数转换为请求结构体
	vo, errStr := parse.Parse(r, &sys_mod.SysUserInfoReq{})
	if vo == nil {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: errStr})
		return
	}
	req := vo.(*sys_mod.SysUserInfoReq)
	// 通过头部请求的token获取用户信息
	token := r.Header.Get("token")
	userInfo := util.GetUserInfo(token)
	if userInfo == nil {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，您未登录或登录超时，请登录！"})
		return
	}
	// 过滤关键参数值中的非法字符
	req.UserId = util.InputFilter(req.UserId, true)
	req.Usname = util.InputFilter(req.Usname, true)
	req.OldPasswd = util.InputFilter(req.OldPasswd, true)
	req.AgnPasswd = util.InputFilter(req.AgnPasswd, true)
	req.NewPasswd = util.InputFilter(req.NewPasswd, true)
	req.NickName = util.InputFilter(req.NickName, true)
	var result *model.Result
	if req.OldPasswd != "" {
		// 判断原密码是否正确
		sysPasswd := sys_serv.SysUserServ.GetPasswd(req.UserId)
		if sysPasswd == "" || req.OldPasswd != sysPasswd {
			util.ToJson(w, &model.ResJson{Code: 400, Msg: "对不起，您输入原密码不正确，请重试！"})
			return
		}
		// 判断两次输入的新密码是否一致
		req.OldPasswd = fmt.Sprintf("%x", md5.Sum([]byte(req.OldPasswd)))
		if req.NewPasswd == "" || req.AgnPasswd == "" || req.NewPasswd != req.AgnPasswd || len(req.AgnPasswd) < 6 || len(req.AgnPasswd) > 30 {
			util.ToJson(w, &model.ResJson{Code: 400, Msg: "对不起，您输入的两次密码不一致，请重试！"})
			return
		}
		req.NewPasswd = fmt.Sprintf("%x", md5.Sum([]byte(req.NewPasswd)))
	}
	result = sys_serv.SysUserServ.Personal(req)
	if result != nil && result.RetCode == 1001 {
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, ModCode: "10010105", Kind: 3, OptOrg: userInfo.DeptId}
		sys_serv.SysLogServ.Add(logReq)
		util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok"})
	} else {
		util.ToJson(w, &model.ResJson{Code: 500, Msg: result.RetMsg})
	}
}

// One 获取用户详情
func (c *sysUser) One(w http.ResponseWriter, r *http.Request) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get("token")
	userInfo := util.GetUserInfo(token)
	if userInfo == nil {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，您未登录或登录超时，请登录！"})
		return
	}
	u := r.URL.Query()
	if u == nil {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: "对不起，请求的参数不能为空，请重试"})
		return
	}
	userId := u.Get("userId")
	// 过滤关键参数值中的非法字符
	userId = util.InputFilter(userId, true)
	if userId == "" || len(userId) != 21 {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: "对不起，请求的编号参数为空或不正确，请重试！"})
		return
	}
	result := sys_serv.SysUserServ.One(userId)
	if result != nil && result.RetCode == 1001 {
		util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok", Data: result.RetData})
	} else {
		util.ToJson(w, &model.ResJson{Code: 404, Msg: result.RetMsg})
	}
}

// Page 获取用户树状列表
func (c *sysUser) Page(w http.ResponseWriter, r *http.Request) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get("token")
	userInfo := util.GetUserInfo(token)
	if userInfo == nil {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，您未登录或登录超时，请登录！"})
		return
	}
	u := r.URL.Query()
	if u == nil {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: "对不起，请求的参数不能为空，请重试"})
		return
	}
	// 获取请求的参数
	schName := u.Get("schName")
	roleId := u.Get("roleId")
	deptId := u.Get("deptId")
	stateses := u.Get("states")
	limits := u.Get("limit")
	offsets := u.Get("offset")
	// 过滤关键参数值中的非法字符
	schName = util.InputFilter(schName, false)
	roleId = util.InputFilter(roleId, true)
	deptId = util.InputFilter(deptId, true)
	stateses = util.InputFilter(stateses, true)
	limits = util.InputFilter(limits, true)
	offsets = util.InputFilter(offsets, true)
	states := convert.Str2u8(stateses)
	limit := convert.Str2u8(limits)
	offset := convert.Str2u32(offsets)
	// 先统计信息的数量
	req := &sys_mod.SysUserPageReq{SchName: schName, RoleId: roleId, States: states, DeptId: deptId}
	if result := sys_serv.SysUserServ.Count(req); result != nil && result.RetCode == 1001 && result.RetData.(int64) > 0 {
		res := &sys_mod.SysUserPageRes{Total: result.RetData.(int64)}
		// 再查询具体的信息列表
		req.Limit = limit
		req.Offset = offset
		if result = sys_serv.SysUserServ.Page(req); result != nil && result.RetCode == 1001 {
			res.List = result.RetData
			util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok", Data: res})
			return
		}
	}
	util.ToJson(w, &model.ResJson{Code: 404, Msg: "暂无内容"})
}

// Select 获取用户下拉列表
func (c *sysUser) Select(w http.ResponseWriter, r *http.Request) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get("token")
	userInfo := util.GetUserInfo(token)
	if userInfo == nil {
		util.ToJson(w, &model.ResJson{Code: 401, Msg: "对不起，您未登录或登录超时，请登录！"})
		return
	}
	u := r.URL.Query()
	if u == nil {
		util.ToJson(w, &model.ResJson{Code: 400, Msg: "对不起，请求的参数不能为空，请重试"})
		return
	}
	// 获取请求的参数
	schName := u.Get("schName")
	deptId := u.Get("deptId")
	// 过滤关键参数值中的非法字符
	schName = util.InputFilter(schName, false)
	deptId = util.InputFilter(deptId, true)
	req := &sys_mod.SysUserSelReq{SchName: schName, DeptId: deptId}
	result := sys_serv.SysUserServ.Select(req)
	if result != nil && result.RetCode == 1001 {
		util.ToJson(w, &model.ResJson{Code: 200, Msg: "ok", Data: result.RetData})
	} else {
		util.ToJson(w, &model.ResJson{Code: 404, Msg: result.RetMsg})
	}
}
